#!/bin/bash
set -o errexit
set -o pipefail

origin_pkgsrc=https://pkgsrc.smartos.org
pkgsrc=https://pkgsrc.itime.biz:4443
enable_svc="0"
lower_case="0"
skip_bin_log="0"
port="3306"
mysql_data_path=/var/mysql
mysql_log_path=/var/log/mysql
mysql_backups_path=/var/backups/percona

zoneid=$(zonename)
# 如有slog，设置为 latency， 否则设置为 throughput
logbias=latency
zpool status|grep cache 1>/dev/null 2>&1 || logbias=throughput

function usage(){
    echo "usage:"    
    echo "  $(basename $0) [-h] [-e] [-l] [--skip-bin-log] [-s <pkgsrc_source>] [-c <mycnf_url>] [-p <root_password>] [--port <port>]"  
    echo "    options:" 
    echo "      --help|-h 显示使用帮助, 可选"
    echo "      --enable|-e 安装完成后启动mysql服务, 默认不启动"
    echo "      --pkgsrc|-s <pkgsrc_source> pkgsrc源地址, 如 http://192.168.1.112:8080"    
    echo "      --mycnf|-c <mycnf_url> my.cnf远程地址, 用于替换 my.cnf"    
    echo "      --lower-case|-l 启用小写模式"   
    echo "      --skip-bin-log 不记录bin log, 默认为记录bin log"   
    echo "      --password|-p <root_password> mysql root用户密码, 默认为空"
    echo "      --port <port> 指定mysql端口, 默认为 3306"
    exit
}


function fatal(){
  echo "$1"
  exit 1
}

while [[ $# -ge 1 ]]; do
    case $1 in
        -pkgsrc|-s )
            pkgsrc=$2
            shift 2
            ;;
        --mycnf|-c )
            my_cnf_url=$2
            shift 2
            ;;
        --password|-p )
            root_password=$2
            shift 2
            ;;  
        --port )
            port=$2
            shift 2
            ;;  
        -e|--enable )
            enable_svc="1"
            shift
            ;; 
        --lower-case|-l )   
            lower_case="1"
            shift
            ;; 
        --skip-bin-log )   
            skip_bin_log="1"
            shift
            ;; 
        -h|--help )
            usage
            ;;
        * )            
            echo ""
            echo "不支持的参数: $1"
            echo ""
            usage            
            ;;
    esac
done

zfs list zones/${zoneid}/data/mysql-data 1>/dev/null 2>&1 || data_dataset="0"
if [ "${data_dataset}" == "0" ]; then
    echo "create datasets..."
    zfs set mountpoint=/data zones/${zoneid}/data
    zfs create -o mountpoint=${mysql_log_path} zones/${zoneid}/data/mysql-log
    zfs create -o mountpoint=${mysql_data_path} -o recordsize=16k -o primarycache=metadata -o logbias=${logbias} zones/${zoneid}/data/mysql-data
    zfs create -o mountpoint=${mysql_backups_path} zones/${zoneid}/data/mysql-backups
fi

if [ "${my_cnf_url}" != "" ]; then    
    echo "download my.cnf from ${my_cnf_url}..."
    wget -o /opt/local/etc/my.cnf --no-check-certificate ${my_cnf_url}
fi

# 设置 pkgsrc
if [ "${pkgsrc}" != "" ]; then
    echo "update pkgsrc to ${pkgsrc}..."
    minimal="1"
    sed -i '' "s|^${origin_pkgsrc}|${pkgsrc}|" /opt/local/etc/pkgin/repositories.conf 1>/dev/null 2>&1 || minimal="0"
    if [ "${minimal}" == "1" ]; then        
        sed -i '' "s|^PKG_PATH=${origin_pkgsrc}|PKG_PATH=${pkgsrc}|" /opt/local/etc/pkg_install.conf 
    else
        gsed -i "s|^${origin_pkgsrc}|${pkgsrc}|" /opt/local/etc/pkgin/repositories.conf
        gsed -i "s|^PKG_PATH=${origin_pkgsrc}|PKG_PATH=${pkgsrc}|" /opt/local/etc/pkg_install.conf
    fi
fi

# 统一使用 gsed
echo "install gsed ..."
pkgin -y in gsed

echo "install percona-server..."
# 安装 percona server
pkgin -y in percona-server 1>/dev/null 2>&1

pkgin -y in percona-xtrabackup quickbackup-percona


echo "getting qb_pw"
QB_PW=${QB_PW:-$(mdata-get mysql_qb_pass 2>/dev/null)} || \
QB_PW=$(od -An -N8 -x /dev/random | head -1 | sed 's/^[ \t]*//' | tr -d ' ');
QB_US=qb-$(zonename | awk -F\- '{ print $1 }');

# Default query to lock down access and clean up
MYSQL_INIT="GRANT ALL on *.* to 'root'@'localhost' with grant option;
CREATE USER IF NOT EXISTS '${QB_US}'@'localhost' IDENTIFIED BY '${QB_PW}';
GRANT LOCK TABLES,SELECT,RELOAD,SUPER,PROCESS,BACKUP_ADMIN,REPLICATION CLIENT on *.* to '${QB_US}'@'localhost';
FLUSH PRIVILEGES;
FLUSH TABLES;"



chown -R mysql:mysql ${mysql_backups_path}

if [ "${my_cnf_url}" == "" ]; then 
    echo "replace MySQL configuration"
    gsed -i \
        -e "s/bind-address = 127.0.0.1/bind-address = 0.0.0.0/" \
        -e "s/utf8/utf8mb4/" \
        -e "/^server-id/iskip-log-bin\ndefault_authentication_plugin = mysql_native_password\nsql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,ERROR_FOR_DIVISION_BY_ZERO\n" \
        -e "/^innodb_write_io_threads =/a\ \ninnodb_flush_neighbors = 0\ninnodb_fast_shutdown = 2\ninnodb_flush_method = fsync\ninnodb_use_native_aio = 0" \
        -e "s|innodb_log_group_home_dir = /var/mysql|innodb_log_group_home_dir = ${mysql_log_path}|" \
        -e "s|datadir = /var/mysql|datadir = ${mysql_data_path}|" \
        -e "s|innodb_data_home_dir = /var/mysql|innodb_data_home_dir = ${mysql_data_path}|" \
        -e "s/expire_logs_days = 7/binlog_expire_logs_seconds = 604800/" \
    /opt/local/etc/my.cnf
    
    
    MEMCAP=$(kstat -c zone_memory_cap -s physcap -p | cut -f2 | awk '{ printf "%d", $1/1024/1024 }');

    # innodb_buffer_pool_size
    INNODB_BUFFER_POOL_SIZE=$(echo -e "scale=0; ${MEMCAP}/2"|bc)M

    # back_log
    BACK_LOG=64
    [[ ${MEMCAP} -gt 8000 ]] && BACK_LOG=128

    # max_connections
    [[ ${MEMCAP} -lt 1000 ]] && MAX_CONNECTIONS=200
    [[ ${MEMCAP} -gt 1000 ]] && MAX_CONNECTIONS=500
    [[ ${MEMCAP} -gt 2000 ]] && MAX_CONNECTIONS=1000
    #[[ ${MEMCAP} -gt 3000 ]] && MAX_CONNECTIONS=2000
    #[[ ${MEMCAP} -gt 5000 ]] && MAX_CONNECTIONS=5000

    # thread_cache_size
    THREAD_CACHE_SIZE=$((${MAX_CONNECTIONS}/2))
    [[ ${THREAD_CACHE_SIZE} -gt 1000 ]] && THREAD_CACHE_SIZE=1000
    echo "tuning MySQL configuration"
    gsed -i \
        -e "s/back_log = 64/back_log = ${BACK_LOG}/" \
        -e "s/thread_cache_size = 1000/thread_cache_size = ${THREAD_CACHE_SIZE}/" \
        -e "s/max_connections = 1000/max_connections = ${MAX_CONNECTIONS}/" \
        -e "s/innodb_buffer_pool_size = [0-9]*M/innodb_buffer_pool_size = ${INNODB_BUFFER_POOL_SIZE}/" \
        -e "s/net_buffer_length = 2K/net_buffer_length = 16384/" \
    /opt/local/etc/my.cnf
fi

if [ "${lower_case}" == "1" ]; then
    echo "set lower_case_table_names = 1"
    gsed -i \
        -e "/^server-id/ilower_case_table_names = 1\n" \
        /opt/local/etc/my.cnf
fi

if [ "${skip_bin_log}" == "1" ]; then
    echo "set skip-log-bin"
    gsed -i \
        -e "/^#binlog-ignore-db/a\ \nskip-log-bin" \
        /opt/local/etc/my.cnf
fi

if [ "${port}" != "3306" ]; then
    echo "set port = ${port}"
    gsed -i \
        -e "s/port = 3306/port = ${port}/" \
        /opt/local/etc/my.cnf
fi

echo "initialize mysql ..."
rm -rf ${mysql_data_path}/* ${mysql_log_path}/*

mysqld --user=mysql --initialize-insecure

if [ "${enable_svc}" == "1" ]; then
    echo "install percona-server..."
    # 启用服务
    svcadm enable -r svc:/pkgsrc/percona:default
fi

svc_status=$(svcs -H percona|cut -d' ' -f1)
if [ "${svc_status}" == "disabled" ]; then
    svcadm enable -r svc:/pkgsrc/percona:default
fi

# 等待 服务成功启动
sleep 5    

echo "running the access lockdown SQL query"
if [[ $(mysql -uroot --skip-password -e "select version()" &>/dev/null)$? -eq "0" ]]; then
    mysql -u root --skip-password -e "${MYSQL_INIT}" >/dev/null || ( echo "ERROR MySQL query failed to execute." && exit 31; )
else
    echo "Can't login with no password set, continuing.";
fi

if [ "${root_password}" != "" ]; then
    echo "change root password..."
    /opt/local/bin/mysqladmin -u root password ${root_password}
    
else
    echo "root password is empty!"
fi

echo "root password is '${root_password}', backup-username: ${QB_US}, backup-password: ${QB_PW}"

echo "configuring Quickbackup"
svccfg -s quickbackup-percona setprop quickbackup/username = astring: ${QB_US}
svccfg -s quickbackup-percona setprop quickbackup/password = astring: ${QB_PW}
svcadm refresh quickbackup-percona

svcadm enable -r quickbackup-percona

if [ "${enable_svc}" != "1" ]; then
    svcadm disable svc:/pkgsrc/percona:default
fi

echo "install successful!"